/*******************************************************************************
 * 
 * Copyright:
 * 
 * License:
 * 
 * Authors: SALMON Charles
 * 
 ******************************************************************************/

/*******************************************************************************
 * 
 ******************************************************************************/

/**
 * A list that is binded to existing topics
 * It supports a simple filtering
 * To start list population, call bip.services.SynchronizedTopics.getInstance().fetchTopics()
 */
qx.Class.define("bip.ui.form.SynchronizedTopicList",  
{
extend : qx.ui.core.Widget,
  
implement : [
       qx.ui.core.IMultiSelection,
       qx.ui.form.IForm,
       qx.ui.form.IModelSelection
     ],

include : [
       qx.ui.core.MRemoteChildrenHandling,
       qx.ui.core.MMultiSelectionHandling,
       qx.ui.form.MForm,
       qx.ui.form.MModelSelection
     ],
     
 /*
  *****************************************************************************
     CONSTRUCTOR
  *****************************************************************************
  */
  construct : function()
  {
    this.base(arguments);
    
    // initialize the layout
    var layout = new qx.ui.layout.VBox();
    this._setLayout(layout);
   
    // create the widgets
    this._createChildControl("filter");
    var list = this._createChildControl("list");
    
    // Used to fire item add/remove events
    list.addListener("addItem", this._onAddChild, this);
    list.addListener("removeItem", this._onRemoveChild, this);
    
    this.SELECTION_MANAGER = list.SELECTION_MANAGER;
    
    // Handles binding
    
    // SERVICE
		var service = bip.services.SynchronizedTopics.getInstance();
		service.addListener("error",function(evt) {
			this.removeAll();
			this.add(new qx.ui.form.ListItem("Error:"+evt.getData().getMessage()));
    },this);
		
		// BINDING
		this.__controller = new qx.data.controller.List(null, list);
		this.__controller.setDelegate({
			createItem : function() {
				return new bip.ui.form.TopicListItem();
			},
	    
			bindItem : function(controller, item, id) {
				item.setModel(controller.getModel().getItem(id));
				//qx.log.Logger.debug(bip.ui.form.SynchronizedTopicList,qx.dev.Debug.debugProperties(controller.getModel().getItem(id)));
				controller.bindProperty("name", "label", null, item, id);
				controller.bindProperty("idTopic", "id", null, item, id);
				controller.bindProperty("idLocal", "icon", null, item, id);
			},
			
			filter : function( data) {
				if (data.getName() == null) { return false;}
				if (data.getIdTopic() < 0) { return false;}
				return true;
			}
		});
		
		service.bind("topics", this.__controller, "model");
		
  },
  
  /*
   *****************************************************************************
      EVENTS
   *****************************************************************************
   */


   events :
   {
     /**
      * This event is fired after a list item was added to the list. The
      * {@link qx.event.type.Data#getData} method of the event returns the
      * added item.
      */
     addItem : "qx.event.type.Data",

     /**
      * This event is fired after a list item has been removed from the list.
      * The {@link qx.event.type.Data#getData} method of the event returns the
      * removed item.
      */
     removeItem : "qx.event.type.Data"
   },
  
   
   /*****************************************************************************
      PROPERTIES
   *****************************************************************************/
   
   properties :
   {
     // overridden
     appearance :
     {
       refine : true,
       init : "list"
     },
     
     value :
     {
       check : "Integer",
       nullable : true,
       event : "changeValue",
       apply : "_applyValue"
     }
   },
   
   
    /*****************************************************************************
       MEMBERS
    *****************************************************************************/
    
    members :
    {
    	_searchTextField:null,
    	_status:null,
    	__controller:null,
    	
    	getController: function() {
    		return this.__controller;
    	},
    	
    	/*
      ---------------------------------------------------------------------------
        WIDGET API
      ---------------------------------------------------------------------------
      */


      // overridden
      getChildrenContainer : function() {
        return this.getChildControl("list").getChildrenContainer();
      },

      /**
       * Handle child widget adds on the content pane
       *
       * @param e {qx.event.type.Data} the event instance
       */
      _onAddChild : function(e) {
        this.fireDataEvent("addItem", e.getData());
      },

      /**
       * Handle child widget removes on the content pane
       *
       * @param e {qx.event.type.Data} the event instance
       */
      _onRemoveChild : function(e) {
        this.fireDataEvent("removeItem", e.getData());
      },
    	
      // overridden
      _createChildControlImpl : function(id)
      {
        var control;

        switch(id)
        {        
        	case "filter":
        		control = this._createFilter();
        		control.setHeight(20);
            this._add(control);
            break;
        		
          case "list":
            control = new qx.ui.form.List();
            this._add(control,{flex:1});
            break;
        }

        return control || this.base(arguments, id);
      },
    	
    	_createFilter:function() {
        var searchComposlite = new qx.ui.container.Composite();
        searchComposlite.setLayout(new qx.ui.layout.HBox(0));
        searchComposlite.setAppearance("textfield");
        searchComposlite.setPadding(0);
        searchComposlite.setMargin(-1);

        var searchIcon = new qx.ui.basic.Image("icon/16/actions/edit-find.png");
        searchComposlite.add(searchIcon);

        this._searchTextField = new qx.ui.form.TextField();
        this._searchTextField.setLiveUpdate(true);
        this._searchTextField.setAppearance("widget");
        this._searchTextField.setPlaceholder(this.tr("Type 'en' to get all english topics, '12' for topics with id=12, ..."));

        var filterTimer = new qx.event.Timer(500);
        filterTimer.addListener("interval", function(ev) {
          this.filter(this._searchTextField.getValue());
          filterTimer.stop();
        }, this);

        this._searchTextField.addListener("changeValue", function(ev) {
          filterTimer.restart();
        }, this);

        searchComposlite.add(this._searchTextField, {flex: 1});
        
        // create the status of the list
        this._status = new qx.ui.basic.Label("");
        this._status.setAppearance("widget");
        this._status.setWidth(80);
        this._status.setTextAlign("right");
        searchComposlite.add(this._status);
        searchComposlite.setMaxHeight(20);
        return searchComposlite;
    	},
    	
    	// ------------------------------------------------------------------------
      //   FILTER
      // ------------------------------------------------------------------------

      /**
       * This method filters the items in the list
       * @param term {String} The search term.
       */
      filter : function(term)
      {
      	var searchRegExp = new RegExp("^.*" + term + ".*", "ig");
        var items = this.getChildren();

        var showing = 0;
        var count = 0;
        for (var i = 0; i < items.length; i++) {
          var item = items[i];
          
          if (item.getIcon().match(searchRegExp)) {
            	item.show();
            	showing++;
          } 
          else if ((item.getId()+"").match(searchRegExp)) {
          	item.show();
          	showing++;
          } 
          else if (item.getLabel().match(searchRegExp)) {
          	item.show();
          	showing++;
          } 
          else {
          	item.exclude();
          }
          count++;
          
        }

        // update the status
        this._status.setValue(showing + "/" + count);
      }
    },
    
    
     /*****************************************************************************
        DESTRUCTOR
     *****************************************************************************/
     

     destruct : function() {
       this._disposeObjects("_searchTextField","_status","__controller");
     }
  
});
